package me.zhengjie.modules.system.util;

import com.aliyun.oss.*;
import com.aliyun.oss.model.*;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.io.*;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;


/**
 * aliyun-oss对象存储服务文件工具类
 * 
 * @author caijiaolong
 * @version 1.0
 * @date 2019年07月24日 下午17:49:32
 */
public class OSSClientUtil {
	private static final Log logger = LogFactory.getLog(OSSClientUtil.class);
	// endpoint是访问OSS的域名。
//	private static final String endpoint = "http://oss-cn-qingdao.aliyuncs.com";
	private static final String endpoint = "http://oss-cn-shanghai.aliyuncs.com";
	private static final String accessKeyId = "LTAI7qI85FmZh3QI";
	private static final String accessKeySecret = "JPdhvQ1K9XgJqW3AxKyyeQ4gfAMKv9";
	//上线之后需要修改地址，后期js，css文件等等全部放到里面去

	private static OSSClientUtil instance;

	private static String bucketName ="renwenhuangpu";
	/*
	 * 使用阿里云账户构造一个客户端实例来访问OSS
	 */
	private static OSSClient ossClient = null;

	/**
	 * 初始化实列
	 *
	 * @return
	 */
	public static synchronized OSSClientUtil getInstance(String name) {
		if (instance == null) {
			instance = new OSSClientUtil();
		}
		if (null != name){
			bucketName = name;
		}
		return instance;
	}

	/**
	 * 判断给定的Bucket是否存在 不存在则新建 默认权限为公共读
	 *
	 */
	private static void doesBucketExist(String bucketName) throws OSSException {
		ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
		// 判断给定的Bucket是否存在
		if (!ossClient.doesBucketExist(bucketName)) {
			// 不存在则新建
			logger.error(bucketName + "不存在  创建bucket： " + bucketName + "\n");
			ossClient.createBucket(bucketName);
			CreateBucketRequest createBucketRequest = new CreateBucketRequest(bucketName);
			createBucketRequest.setCannedACL(CannedAccessControlList.PublicRead);// 设置为公共读权限
			ossClient.createBucket(createBucketRequest);
			ossClient.shutdown();
		}
	}

	/**
	 * 创建bucket
	 *
	 * @param1 bucket名称
	 * @param2 bucket读写权限
	 */
	@SuppressWarnings("unused")
	private static void createBucket(String bucketName, CannedAccessControlList CannedAccess) throws OSSException {
		ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
		// 判断给定的Bucket是否存在
		if (!ossClient.doesBucketExist(bucketName)) {
			logger.error(bucketName + "不存在  创建bucket： " + bucketName + "\n");
			ossClient.createBucket(bucketName);
			CreateBucketRequest createBucketRequest = new CreateBucketRequest(bucketName);
			createBucketRequest.setCannedACL(CannedAccess);// 设置bucket权限
			ossClient.createBucket(createBucketRequest);
		} else {
			ossClient.shutdown();
			System.out.println("bucket已经存在了");
			//throw new AppException("IICIPBMS00005", "已存在bucket名称为：" + bucketName);
			//throw new OSSException("已存在bucket名称为：" + bucketName);
		}
		ossClient.shutdown();
	}

	/**
	 * 删除bucket (谨慎使用 删除bucket将会删除bucket空间下所有的对象)
	 *
	 */
	public static void deleteBucket(String bucketName) {
		ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
		// 判断给定的Bucket是否存在
		if (ossClient.doesBucketExist(bucketName)) {
			if (bucketName != null || !"".equals(bucketName)) {
				logger.error("删除bucket： " + bucketName + "\n");
				ossClient.deleteBucket(bucketName);
			}
		}
		ossClient.shutdown();
	}


	/**
	 * 创建模拟文件夹
	 */
	private static void createSimulationFolder(String name) throws IOException {
		try {
			ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
			// 检查bucket存储空间
			doesBucketExist(bucketName);
			if (name.lastIndexOf("/") + 1 != name.length()) {
				name += "/";
			}
			// key是文件名
			ossClient.putObject(bucketName, name, new ByteArrayInputStream(new byte[0]));
		} catch (OSSException oe) {
			logger.error("错误信息: " + oe.getErrorCode());
			logger.error("错误代码:       " + oe.getErrorCode());
			logger.error("Request ID:      " + oe.getRequestId());
			logger.error("Host ID:           " + oe.getHostId());
			oe.printStackTrace();
		} catch (ClientException ce) {
			logger.error("无法连接到oss服务器,请检查");
			logger.error("错误信息: " + ce.getMessage());
			ce.printStackTrace();
		} finally {
			ossClient.shutdown();// 关机
		}
	}
	/**
	 * 读取文件
	 *
	 */
	public static void readFileToFile(String fileName,String bucketName,String destPath) {
		try {
			ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
			// 检查bucket存储空间
			doesBucketExist(bucketName);

			boolean exists = ossClient.doesObjectExist(bucketName, fileName);
			if (exists) {
				OSSObject object = ossClient.getObject(bucketName, fileName);
                writeToLocal(destPath,object.getObjectContent());
			}
		} catch (OSSException oe) {
			logger.error("错误信息: " + oe.getErrorCode());
			logger.error("错误代码:       " + oe.getErrorCode());
			logger.error("Request ID:      " + oe.getRequestId());
			logger.error("Host ID:           " + oe.getHostId());
			oe.printStackTrace();
		} catch (ClientException ce) {
			logger.error("Caught an ClientException, which means the client encountered "
					+ "a serious internal problem while trying to communicate with OSS, "
					+ "such as not being able to access the network.");
			logger.error("Error Message: " + ce.getMessage());
			ce.printStackTrace();
		} catch (IOException e) {
            e.printStackTrace();
        } finally {
			ossClient.shutdown();
		}
	}

	public static void writeToLocal(String destination, InputStream input)
			throws IOException {
		int index;
		byte[] bytes = new byte[1024];
		FileOutputStream downloadFile = new FileOutputStream(destination);
		while ((index = input.read(bytes)) != -1) {
			downloadFile.write(bytes, 0, index);
			downloadFile.flush();
		}
		input.close();
		downloadFile.close();

	}



	/**
	 * 删除文件 (删除文件前请务必设置key值 key:为要删除的文件名称)
	 *
	 */
	@SuppressWarnings("unused")
	public static void deleteFile(String fileName) {
		try {
			ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
			// 检查bucket存储空间
			doesBucketExist(bucketName);

			if (fileName != null || "".equals(fileName)) {
				// key是文件名
				ossClient.deleteObject(bucketName, fileName);
			}
		} catch (OSSException oe) {
			logger.error("错误信息: " + oe.getErrorCode());
			logger.error("错误代码:       " + oe.getErrorCode());
			logger.error("Request ID:      " + oe.getRequestId());
			logger.error("Host ID:           " + oe.getHostId());
			oe.printStackTrace();
		} catch (ClientException ce) {
			logger.error("Caught an ClientException, which means the client encountered "
					+ "a serious internal problem while trying to communicate with OSS, "
					+ "such as not being able to access the network.");
			logger.error("Error Message: " + ce.getMessage());
			ce.printStackTrace();
		} finally {
			ossClient.shutdown();
		}
	}

	/**
	 * 写文件到oss
	 *
	 * @param1 流
	 * @param2 要存放在oss上的路径 目录节点用'/'表示 示例:data/img/file.png data:一级目录 img：二级目录
	 *         具体文件名及文件后缀名
	 */
	public static String writeFileByIns(InputStream file, String path,String fileType) throws IOException {
		String filePath = null;
		try {
			path += getFolder() + "/";
			createSimulationFolder(path);// 先根据url创建模拟文件夹
			if (file != null) {
				ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
				// 定义保存的文件名
				String fileName = UUID.randomUUID().toString().replaceAll("-","");
				filePath = path + fileName + "." + fileType;
				// key是文件名
				ossClient.putObject(bucketName, filePath, file);
			}
		} catch (OSSException oe) {
			logger.info("错误信息: " + oe.getErrorCode());
			logger.info("错误代码:       " + oe.getErrorCode());
			logger.info("Request ID:      " + oe.getRequestId());
			logger.info("Host ID:           " + oe.getHostId());
		} catch (ClientException ce) {
			logger.info("Caught an ClientException, which means the client encountered "
					+ "a serious internal problem while trying to communicate with OSS, "
					+ "such as not being able to access the network.");
			logger.info("Error Message: " + ce.getMessage());
		} finally {
			ossClient.shutdown();
		}
		return filePath;
	}

	/**
	 * 写文件到oss
	 *
	 * @param1 本地文件路径
	 * @param2 要存放在oss上的路径 目录节点用'/'表示 示例:data/img/file.png data:一级目录 img：二级目录
	 *         具体文件名及文件后缀名
	 */
	public static void writeFileByFile(File file, String filePath) throws IOException {

		wirteFile(file, filePath, bucketName);
	}

	/**
	 * 写文件到oss
	 *
	 * @param1 本地文件路径
	 * @param2 要存放在oss上的路径 目录节点用'/'表示 示例:data/img/file.png data:一级目录 img：二级目录
	 *         具体文件名及文件后缀名
	 */
	public static void writeFileByFileOnbucketName(File file, String filePath,String bucketName) throws IOException {
		wirteFile(file, filePath, bucketName);
	}

	private static void wirteFile(File file, String filePath, String bucketName) throws IOException {
		logger.info(file.toString()+"...."+filePath+"..."+bucketName);
		try {
			ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
			// 检查bucket存储空间
			doesBucketExist(bucketName);
			// 文件是否存在
			if (!file.exists()) {
				throw new IOException("找不到文件,路径：" + file.getPath());
			}
			// key是文件名
			PutObjectResult putObject = ossClient.putObject(bucketName, filePath, file);
			System.out.println(putObject);
		} catch (OSSException oe) {
			logger.error("错误信息: " + oe.getErrorCode());
			logger.error("错误代码:       " + oe.getErrorCode());
			logger.error("Request ID:      " + oe.getRequestId());
			logger.error("Host ID:           " + oe.getHostId());
			oe.printStackTrace();
		} catch (ClientException ce) {
			logger.error("无法连接到oss服务器,请检查");
			logger.error("错误信息: " + ce.getMessage());
			ce.printStackTrace();
		} finally {
			ossClient.shutdown();
		}
	}

	/**
	 * 写文件到oss
	 *
	 * @param1 本地文件路径
	 * @param2 要存放在oss上的路径 目录节点用'/'表示 示例:data/img/file.png data:一级目录 img：二级目录
	 *         具体文件名及文件后缀名
	 */
	public static void writeFileByByte(byte[] file, String filePath) throws IOException {
		try {
			ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
			// 检查bucket存储空间
			doesBucketExist(bucketName);
			InputStream sbs = new ByteArrayInputStream(file);
			ossClient.putObject(bucketName, filePath, sbs);
		} catch (OSSException oe) {
			logger.error("错误信息: " + oe.getErrorCode());
			logger.error("错误代码:       " + oe.getErrorCode());
			logger.error("Request ID:      " + oe.getRequestId());
			logger.error("Host ID:           " + oe.getHostId());
			oe.printStackTrace();
		} catch (ClientException ce) {
			logger.error("无法连接到oss服务器,请检查");
			logger.error("错误信息: " + ce.getMessage());
			ce.printStackTrace();
		} finally {
			ossClient.shutdown();
		}
	}

	public boolean isFileExits(String filePath) {
		boolean doesObjectExist=false;
		try {
			ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
			// 检查bucket存储空间
			doesObjectExist = ossClient.doesObjectExist(bucketName, filePath);
		} catch (OSSException oe) {
			logger.error("错误信息: " + oe.getErrorCode());
			logger.error("错误代码:       " + oe.getErrorCode());
			logger.error("Request ID:      " + oe.getRequestId());
			logger.error("Host ID:           " + oe.getHostId());
			oe.printStackTrace();
		} catch (ClientException ce) {
			logger.error("无法连接到oss服务器,请检查");
			logger.error("错误信息: " + ce.getMessage());
			ce.printStackTrace();
		} finally {
			ossClient.shutdown();
		}
		return doesObjectExist;
	}

	/**
	 * 远程复制文件
	 *
	 * @param1 流
	 * @param2 要存放在oss上的路径 目录节点用'/'表示 示例:data/img/file.png data:一级目录 img：二级目录
	 *         具体文件名及文件后缀名
	 */
	public static void copyFile(String srcKey, String destKey) throws IOException {
		try {
			ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
			//CopyObjectRequest copyObjectRequest = new CopyObjectRequest(bucketName, srcKey, bucketName, destKey);
			// 设置新的Metadata
//			ObjectMetadata meta = new ObjectMetadata();
//			meta.setContentType("text/html");
//			copyObjectRequest.setNewObjectMetadata(meta);
			// 复制Object
			CopyObjectResult result = ossClient.copyObject(bucketName, srcKey, bucketName, destKey);
			logger.info("ETag: " + result.getETag() + " LastModified: " + result.getLastModified());
		} catch (OSSException oe) {
			logger.error("错误信息: " + oe.getErrorCode());
			logger.error("错误代码:       " + oe.getErrorCode());
			logger.error("Request ID:      " + oe.getRequestId());
			logger.error("Host ID:           " + oe.getHostId());
		} catch (ClientException ce) {
			logger.error("Caught an ClientException, which means the client encountered "
					+ "a serious internal problem while trying to communicate with OSS, "
					+ "such as not being able to access the network.");
			logger.error("Error Message: " + ce.getMessage());
			ce.printStackTrace();
		} finally {
			ossClient.shutdown();
		}
	}
	 public static final byte[] input2byte(InputStream inStream)
	            throws IOException {
	        ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
	        byte[] buff = new byte[100];
	        int rc = 0;
	        while ((rc = inStream.read(buff, 0, 100)) > 0) {
	            swapStream.write(buff, 0, rc);
	        }
	        byte[] in2b = swapStream.toByteArray();
	        return in2b;
	    }





	/**
	 * 远程复制文件
	 * @return
	 *
	 * @param1 流
	 * @param2 要存放在oss上的路径 目录节点用'/'表示 示例:data/img/file.png data:一级目录 img：二级目录
	 *         具体文件名及文件后缀名
	 */
	public static String getFilePath(String realName, String destKey) throws IOException {
		StringBuffer sfBuffer=new StringBuffer();
		sfBuffer.append(destKey).append("/");
		sfBuffer.append(new SimpleDateFormat("yyyyMMddHHmmss").format(new Date())).append("/");
		sfBuffer.append(UUID.randomUUID().toString().substring(1, 10));
		sfBuffer.append(realName);
		return sfBuffer.toString();
	}


	/**
	 * 年月日目录
	 *
	 * @return
	 */
	private static String getFolder() {
		SimpleDateFormat formater = new SimpleDateFormat("yyyyMMdd");
		return formater.format(new Date());
	}

	/**
	 * 截取视频图片并且上传到oss
	 * @param
	 * objectName 为所在的bucket目录
	 */
	public static String uploadVedioImg(String objectName) throws IOException {
		ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
		String style = "video/snapshot,t_17000,f_jpg,w_800,h_600";
	// 指定过期时间为10分钟。
		Date expiration = new Date(new Date().getTime() + 1000 * 60 * 10 );
		GeneratePresignedUrlRequest req = new GeneratePresignedUrlRequest(bucketName, objectName, HttpMethod.GET);
		req.setExpiration(expiration);
		req.setProcess(style);
		URL signedUrl = ossClient.generatePresignedUrl(req);
		System.out.println(signedUrl);
		ossClient.shutdown();
		return signedUrl.toString();
	}


	public static void main(String[] args) throws IOException {


		uploadVedioImg("zhuanma/20230505083033%E6%84%9A%E5%9B%AD%E8%B7%AF%E5%8E%86%E5%8F%B2%E5%90%8D%E4%BA%BA%E5%A2%99.mp4");
//		OSSClient ossClient=new OSSClient(endpoint, accessKeyId, accessKeySecret);
//
//        OSSObject ossObject = OSSClientUtil.readFile("WechatIMG246.jpeg","qd-zkb");
//
//
////        OSSObject object = ossClient.getObject(bucketName, "WechatIMG246.jpeg");
//		writeToLocal("/tmp/aaa/bbbb.png",ossObject.getObjectContent());
//		ObjectMetadata objecta = ossClient.getObject(new GetObjectRequest(bucketName, "WechatIMG246.jpeg"), new File("/tmp/aaa/aaaa.png"));






//			// 检查bucket存储空间
//			doesBucketExist(bucketName);
//			// 文件是否存在
//			if (!file.exists()) {
//				throw new IOException("找不到文件,路径：" + file.getPath());
//			}
//			// key是文件名
//			ossClient.putObject(bucketName, "oks", file);
//			ossClient.shutdown();
		//String srcKey="tubiao.png";
		//	String destKey="mnt/icipFile/13300850f3a94843af5999b548ea96b4.JPG";
		// 复制Object
		//CopyObjectResult result = ossClient.copyObject(bucketName, srcKey, bucketName, destKey);
		//logger.info("ETag: " + result.getETag() + " LastModified: " + result.getLastModified());
	}





}